import base64
import io
import traceback

import PIL
from PIL import Image
from PIL.ExifTags import TAGS
from xjlibrary.our_file_dir.base_file import CommonFile

"""
https://blog.csdn.net/icamera0/article/details/50843172
"""


class ImageFile(CommonFile):
    @classmethod
    def get_image_exif_data(cls, fname):
        """Get embedded EXIF data from image file.
        获取图片文件中隐藏的信息
        """
        ret = {}
        try:
            img = Image.open(fname)
            if hasattr(img, '_getexif'):
                exifinfo = img._getexif()
                if exifinfo is not None:
                    for tag, value in exifinfo.items():
                        decoded = TAGS.get(tag, tag)
                        ret[decoded] = value
        except IOError:
            print('IOERROR ' + fname)
        return ret

    @classmethod
    def img_to_format_jpg(cls, buf, dstFile):
        """
        vip 图片标准程序
        :param buf:
        :param dstFile:
        :return:
        """
        print('Img2Jpg %s ...' % dstFile)
        # from PIL import ImageFile
        # ImageFile.LOAD_TRUNCATED_IMAGES = True
        exMsg = ''
        try:
            srcImg = Image.open(io.BytesIO(buf))
            dstImg = srcImg.resize((108, 150), Image.ANTIALIAS).convert('RGB')
            dstImg.save(dstFile, 'JPEG')
        except:
            exMsg = '* %s' % traceback.format_exc()
            print(exMsg)
        if exMsg:
            return False

        return True

    @classmethod
    def save_img_to_jpg(cls, buf, dstFile):
        """
        :param buf:
        :param dstFile:
        :return:
        """
        exMsg = ''
        try:
            srcImg = Image.open(io.BytesIO(buf))
            srcImg.save(dstFile, format='JPEG')
        except:
            exMsg = '* %s' % traceback.format_exc()
            print(exMsg)
        if exMsg:
            return False

        return True

    @classmethod
    def save_img(cls, buf, dstFile, format="JPEG"):
        """
        :param buf:
        :param dstFile:
        :return:
        """
        exMsg = ''
        try:
            srcImg = Image.open(io.BytesIO(buf))
            srcImg.save(dstFile, format=format)
        except:
            exMsg = '* %s' % traceback.format_exc()
            print(exMsg)
        if exMsg:
            return False

        return True

    @classmethod
    def is_img(cls, ext):
        """
        传入后缀
        判断是不是图片文件 后期加入更多文件后缀
        :param ext:
        :return:
        """
        ext = ext.lower()
        if ext == '.jpg':
            return True
        elif ext == '.png':
            return True
        elif ext == '.jpeg':
            return True
        elif ext == '.bmp':
            return True
        else:
            return False

    @classmethod
    def resize_image(self, filein, fileout, width, height, type):
        """
                filein:  输入图片
                fileout: 输出图片
                width: 输出图片宽度
                height:输出图片高度
                type:输出图片类型（png, gif, jpeg...）
        """
        img = Image.open(filein)
        out = img.resize((width, height), Image.ANTIALIAS)  # resize image with high-quality
        out.save(fileout, type)

    @classmethod
    def get_image_file_format(self, filepath):
        """
        获取图片的格式 不是通过后缀来判断格式
        :param filename:
        :return:
        """
        image = Image.open(filepath)
        return image.format

    def get_image_file_mode(self, filepath):
        """
        图片模式。图片使用的像素格式，典型的格式有 “1”, “L”, “RGB”, or “CMYK.”
        :param filepath:
        :return:
        """
        image = Image.open(filepath)
        return image.mode

    def get_image_file_size(self, filepath):
        """
        image.size 图片尺寸（以像素为单位）.
        image.width 图片像素宽
        image.height 图片像素高

        :param filepath:
        :return:
        """
        image = Image.open(filepath)
        return image.size, image.width, image.height

    def get_image_file_palette(self, filepath):
        """
        调色板。如果模式是“P”，则是一个ImagePalette类的实例。
        类型: ImagePalette or None
        :param filepath:
        :return:
        """
        image = Image.open(filepath)
        return image.palette

    def get_image_file_info(self, filepath):
        """
        一个与图片有关的数据组成的字典。
        :param filepath:
        :return:
        """
        image = Image.open(filepath)
        return image.info

    @classmethod
    def get_image_to_base64(self, base64str):
        """
        通过base64转图片
        :param base64str:
        :return:  bytes
        """
        convert_img_raw_data = base64.b64decode(base64str)
        return convert_img_raw_data

    @classmethod
    def show_img(cls, path):
        import matplotlib.pyplot as plt
        img = Image.open(path)
        # plt.figure("dog")
        plt.imshow(img)
        plt.show()

    @classmethod
    def get_screen(cls, imagepath, savepath, x, y, w, h):
        im = Image.open(imagepath)
        region = im.crop((x, y, x + w, y + h))
        region.save(savepath)
